package com.epam.customer;

import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import com.epam.bank.Action;
import com.epam.bank.Bank;
import com.epam.bank.Cashier;
import com.epam.bank.Currency;

public class Customer implements Runnable {
	private final int timeInMillis;
	private Currency currency;
	private int amount;
	private static int count=0;
	private final int ID=++count;
	private static Logger logger = Logger.getLogger(Customer.class);
	
	public Customer(int time,Currency currency, int amount) {
		this.timeInMillis=time;
		this.currency=currency;
		this.amount=amount;
	}
	
	public void run() {
			Bank bank = Bank.getInstance();
			Action action = bank.randomAction();
			serveMe(bank, action);
	}
	
	private void serveMe(Bank bank, Action action) {
		try {
			Cashier cashier=bank.getCashier();
			TimeUnit.MILLISECONDS.sleep(timeInMillis);
			switch (action) {
			case WITHDRAW:
				withdraw(cashier, amount);
				logger.info("("+cashier.getId()+") Withdrowal complete! $"
	                		+cashier.getAmountUSD()+" and "+cashier
	                		.getAmountEUR()+" EUR left!");
				Bank.releaseCashier(cashier);
				break;
			case TRANSFER:
				logger.info("("+cashier.getId()+") Transfer complete!");
				Bank.releaseCashier(cashier);
				break;
			case DEPOSIT:
			case PAY:
				depositOrPay(cashier, amount);
				logger.info("("+cashier.getId()+") Payment complete! $"
						+cashier.getAmountUSD()+" and "+cashier
                		.getAmountEUR()+" EUR left!");
				Bank.releaseCashier(cashier);
				break;
			case EXCHANGE:
				exchange(cashier, amount);
				logger.info("("+cashier.getId()+") Exchange complete! $"
						+cashier.getAmountUSD()+" and "+cashier
                		.getAmountEUR()+" EUR left");
				Bank.releaseCashier(cashier);
				break;
			}
		} catch (InterruptedException e) {
			logger.error("Couldn't serve a customer!");
		}
	}
	
	private void withdraw(Cashier cashier, int amount) {
		switch (this.currency) {
		case USD:
			cashier.decAmountUSD(amount);
			break;
		case EUR:
			cashier.decAmountEUR(amount);
			break;
		}
	}
	
	private void depositOrPay(Cashier cashier, int amount) {
		switch (this.currency) {
		case USD:
			cashier.incAmountUSD(amount);
			break;
		case EUR:
			cashier.incAmountEUR(amount);
			break;
		}
	}
	
	private void exchange(Cashier cashier, int amount) {
		float rate=Bank.getEurUsdRate();
		switch (this.currency) {
		case USD:
			cashier.incAmountUSD(amount);
			cashier.decAmountEUR((int)(amount/rate));
			break;
		case EUR:
			cashier.incAmountEUR(amount);
			cashier.decAmountUSD((int)(amount*rate));
			break;
		}
	}
	
	public Currency getCurrency() {
		return currency;
	}

	public int getAmount() {
		return amount;
	}

	public int getTimeInMillis() {
		return timeInMillis;
	}

}
